package com.xbongbong.pro.statistics.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.XbbConstant;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.enums.EsAliasEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.bi.XbbTableRefEnum;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.bi.commons.helper.CollectionHelper;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.statistic.constant.RelatedProductConstant;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.SelectProductEnum;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.xbongbong.paas.constant.XbbConstant.JSON_EXTRACT;
import static com.xbongbong.paas.constant.XbbConstant.JSON_EXTRACT_RAW;

/**
 * 公用工具方法
 * @ClassName CommonHelper
 * @Author 梁鲁江
 * 创建时间 2022/1/20 11:29
 * 修改时间  2022/1/20 11:29
 **/
@Component
public class CommonHelper {
    public Logger LOG = LoggerFactory.getLogger(getClass());
    @Value("${spring.application.name}")
    private String applicationName;
    @Resource
    private PaasRedisHelper paasRedisHelper;

    private static HashMap<Integer, String> teamUserHashMap = Maps.newHashMap();
    /**
     * 获取formId和表名的对应关系
     *
     * @param chartEntity
     * @param isSingle  是否是单表
     * @return
     */
    public Map<Long, String> getFormIdTableMap(ChartEntity chartEntity, boolean isSingle) {
        Map<Long, String> formIdTableMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Integer driverBusinessType = chartEntity.getDriverSources().getInteger("businessType");
        XbbTableRefEnum xbbTableRefEnum = XbbTableRefEnum.getByCode(driverBusinessType);
        formIdTableMap.put(chartEntity.getDriverSources().getLong("formId"), xbbTableRefEnum.getTableName());
        if (!isSingle) {
            JSONArray slaveSources = chartEntity.getSlaveSources();
            if (CollectionsUtil.isNotEmpty(slaveSources)) {
                Map<String,Integer> map = new HashMap(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                map.put(xbbTableRefEnum.getTableName(),0);
                for (int i = 0; i < slaveSources.size(); i++) {
                    JSONObject slaveJson = slaveSources.getJSONObject(i);
                    Integer businessType = slaveJson.getInteger("businessType");
                    XbbTableRefEnum tableRefEnum = XbbTableRefEnum.getByCode(businessType);
                    String tableName = tableRefEnum.getTableName();
                    String tableNameAlais = tableName;
                    if(map.containsKey(tableName)){
                        int value = map.get(tableName) + 1;
                        tableNameAlais = tableName + value;
                        map.put(tableName, value);
                    }else {
                        map.put(tableName, 0);
                    }
                    formIdTableMap.put(slaveJson.getLong("formId"), tableNameAlais);
                }
            }
        }
        return formIdTableMap;
    }

    public void setPrintLog(boolean printLog,String corpid){
        String key = applicationName + ":" + corpid;
        if(!printLog){
            //删除缓存
            paasRedisHelper.removeValue(RedisPrefixConstant.PRINT_CHART_SQL_LOG_KEY,key);
            return;
        }
        //以公司维度新增缓存，时长一小时
        paasRedisHelper.setValue(RedisPrefixConstant.PRINT_CHART_SQL_LOG_KEY,key,printLog, RedisConstant.ONE_HOUR);
    }

    /**
     * 查询日志默认关闭
     */
    public boolean getPrintLog (String corpid) {
        String booleanStr;
        try {
            String key = applicationName + ":" + corpid;
            booleanStr = paasRedisHelper.getValue(RedisPrefixConstant.PRINT_CHART_SQL_LOG_KEY, key);
        } catch (Exception e) {
            LOG.error("", e);
            return false;
        }
        if (StringUtil.isEmpty(booleanStr)) {
            return false;
        }
        try {
            return Boolean.valueOf(booleanStr);
        } catch (Exception e) {
            LOG.error("", e);
            return false;
        }
    }

    /**
     * @author  gzt
     * @Description 根据JSON_EXTRACT函数类型确定拼接sql
     * @Date 10:23 2022/4/6
     * @return java.lang.String
     * @throws
     **/

    public static String getExtractString(String jsonExtract,String formId,String linkedText) {
        String extractString;
        if (Objects.isNull(formId)) {
            formId = "";
        }else {
            formId = String.format("%s%s", formId, XbbConstant.POINT);
        }
        if (StringUtils.equals(jsonExtract, XbbConstant.JSON_EXTRACT)) {
            //extractString = jsonExtract + "(" +formId+ "`data`,'" + linkedText + "','"+XbbConstant.STRING_CONSTANT+"') ";
            extractString = MessageFormat.format("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}", jsonExtract, XbbConstant.L_P, formId, XbbConstant.DATA, XbbConstant.SQL_COMMA, XbbConstant.SINGLE_QUOTES, linkedText, XbbConstant.SINGLE_QUOTES, XbbConstant.SQL_COMMA, XbbConstant.SINGLE_QUOTES, XbbConstant.STRING_CONSTANT, XbbConstant.SINGLE_QUOTES, XbbConstant.R_P, XbbConstant.SPACE);
        }else{
            //extractString = jsonExtract + "(" +formId+ "`data`,'" + linkedText + "') ";
            extractString = MessageFormat.format("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}", jsonExtract, XbbConstant.L_P, formId, XbbConstant.DATA, XbbConstant.SQL_COMMA, XbbConstant.SINGLE_QUOTES, linkedText, XbbConstant.SINGLE_QUOTES, XbbConstant.R_P, XbbConstant.SPACE);
        }
        return extractString;
    }

    /**
     * 处理管理产品的特殊字段（data外的）
     * @param chartEntity
     * @param isSingle
     */
    public void biProductFliter(ChartEntity chartEntity, boolean isSingle) {
        if(!isSingle){
            Integer driverBusinessType = chartEntity.getDriverSources().getInteger("businessType");
            //调拨单关联产品 || 采购合同关联的产品 || 采购退货 || 生产单产品
            if (Objects.equals(XbbTableRefEnum.TRANSFER_PRODUCT.getCode(), driverBusinessType)
                    || Objects.equals(XbbTableRefEnum.PURCHASE_PRODUCT.getCode(), driverBusinessType)
                    || Objects.equals(XbbTableRefEnum.PRODUCTION_ORDER_PRODUCT.getCode(), driverBusinessType)
                    || Objects.equals(XbbTableRefEnum.RETURNEDPURCHASE_PRODUCT.getCode(), driverBusinessType)) {
                JSONArray displayArray = chartEntity.getDisplayAttr();
                JSONArray rowGroupAttr = chartEntity.getRowGroupAttr();
                JSONArray colGroupAttr = chartEntity.getColGroupAttr();
                JSONArray summaryArray = chartEntity.getSummaryAttr();
                JSONArray computedNumAttr = chartEntity.getComputedNumAttr();
                JSONArray chartClassifyArray = chartEntity.getChartClassify();
                JSONArray chartSeriesArray = chartEntity.getChartSeries();
                JSONArray chartValueArray = chartEntity.getChartValue();
                JSONArray chartValueSecondArray = chartEntity.getChartValueSecond();
                JSONArray secondTargetAttr = chartEntity.getSecondTargetAttr();
                JSONArray penetrateArray = chartEntity.getPenetrateAttr();
                JSONArray searchArray = chartEntity.getSearch();
                JSONArray filterArray = chartEntity.getFilter();
                if(replaceAttr(displayArray,driverBusinessType)){
                    chartEntity.setDisplayAttr(displayArray);
                }
                if(replaceAttr(rowGroupAttr,driverBusinessType)){
                    chartEntity.setRowGroupAttr(rowGroupAttr);
                }
                if(replaceAttr(colGroupAttr,driverBusinessType)){
                    chartEntity.setColGroupAttr(colGroupAttr);
                }
                if(replaceAttr(summaryArray,driverBusinessType)){
                    chartEntity.setSummaryAttr(summaryArray);
                }
                if(replaceAttr(computedNumAttr,driverBusinessType)){
                    chartEntity.setComputedAttr(computedNumAttr);
                }
                if(replaceAttr(chartClassifyArray,driverBusinessType)){
                    chartEntity.setChartClassify(chartClassifyArray);
                }
                if(replaceAttr(chartSeriesArray,driverBusinessType)){
                    chartEntity.setChartSeries(chartSeriesArray);
                }
                if(replaceAttr(chartValueArray,driverBusinessType)){
                    chartEntity.setChartValue(chartValueArray);
                }
                if(replaceAttr(chartValueSecondArray,driverBusinessType)){
                    chartEntity.setChartValueSecond(chartValueSecondArray);
                }
                if(replaceAttr(secondTargetAttr,driverBusinessType)){
                    chartEntity.setSecondTargetAttr(secondTargetAttr);
                }
                if(replaceAttr(penetrateArray,driverBusinessType)){
                    chartEntity.setPenetrateAttr(penetrateArray);
                }
                if(replaceAttr(searchArray,driverBusinessType)){
                    chartEntity.setSearch(searchArray);
                }
                if(replaceAttr(filterArray,driverBusinessType)){
                    chartEntity.setFilter(filterArray);
                }
            }
        }
    }

    /**
     * 替换originalAttr和fieldType
     * @param jsonArray
     * @param driverBusinessType
     * @return
     */
    private boolean replaceAttr(JSONArray jsonArray, Integer driverBusinessType) {
        boolean flag = false;
        if(CollectionsUtil.isNotEmpty(jsonArray)){
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                if(Objects.equals(XbbTableRefEnum.PURCHASE_PRODUCT.getCode(), driverBusinessType)){
                    //采购合同产品
                    //num_17
                    if(Objects.equals(jsonObject.getString("originalAttr"), SelectProductEnum.INSTOCK_NUM.getAttr())){
                        jsonObject.put("originalAttr",StringUtil.getDataBaseString(RelatedProductConstant.INSTOCK_NUM));
                        jsonObject.put("fieldType", FieldTypeEnum.SYS_LONG_10.getType());
                        jsonArray.set(i,jsonObject);
                        flag = true;
                    }else if (Objects.equals(jsonObject.getString("originalAttr"), SelectProductEnum.RETURN_NUM.getAttr())){
                        //num_16
                        jsonObject.put("originalAttr",StringUtil.getDataBaseString(RelatedProductConstant.OUTSTOCK_NUM));
                        jsonObject.put("fieldType", FieldTypeEnum.SYS_LONG_10.getType());
                        jsonArray.set(i,jsonObject);
                        flag = true;
                    }
                }else if (Objects.equals(XbbTableRefEnum.TRANSFER_PRODUCT.getCode(), driverBusinessType)){
                    //调拨产品
                    //num_17
                    if(Objects.equals(jsonObject.getString("originalAttr"), SelectProductEnum.INSTOCK_NUM.getAttr())){
                        jsonObject.put("originalAttr",StringUtil.getDataBaseString(RelatedProductConstant.INSTOCK_NUM));
                        jsonObject.put("fieldType", FieldTypeEnum.SYS_LONG_10.getType());
                        jsonArray.set(i,jsonObject);
                        flag = true;
                    }
                }else if (Objects.equals(XbbTableRefEnum.PRODUCTION_ORDER_PRODUCT.getCode(), driverBusinessType) || Objects.equals(XbbTableRefEnum.RETURNEDPURCHASE_PRODUCT.getCode(), driverBusinessType)){
                    //采购退货和生产单产品
                    //num_13
                    if(Objects.equals(jsonObject.getString("originalAttr"), SelectProductEnum.OUTSTOCK_NUM.getAttr())){
                        jsonObject.put("originalAttr",StringUtil.getDataBaseString(RelatedProductConstant.OUTSTOCK_NUM));
                        jsonObject.put("fieldType", FieldTypeEnum.SYS_LONG_10.getType());
                        jsonArray.set(i,jsonObject);
                        flag = true;
                    }
                }
            }
        }
        return flag;
    }
    /**
     * @return java.lang.String
     * @throws
     * @Description 根据filedType。value值确定抽取函数名
     * @Date 19:34 2021/12/13
     * @Param [fieldType, value]
     **/

    public static String getExtractFuntion(Integer fieldType, Object value) {
        String funName = JSON_EXTRACT;
        FieldTypeEnum fieldTypeE = FieldTypeEnum.getFieldTypeEnum(fieldType);
        if (fieldTypeE != null) {
            String esalias = fieldTypeE.getEsalias();
            if (StringUtils.equals(esalias, EsAliasEnum.NUM.getEsAlias())) {
                funName = CommonHelper.getNumExtractFuntion(value);
            } else if (StringUtils.equals(esalias, EsAliasEnum.LONG.getEsAlias()) ||
                    StringUtils.equals(esalias, EsAliasEnum.DATE.getEsAlias())) {
                funName = XbbConstant.JSON_EXTRACT_BIGINT;
            } else if (StringUtils.equals(esalias, EsAliasEnum.ARRAY.getEsAlias())) {
                //todo 特殊类型用arrayrow
                funName = JSON_EXTRACT_RAW;
            } else if (Objects.equals(FieldTypeEnum.DEPT.getType(), fieldType)) {
                funName = XbbConstant.JSON_EXTRACT_BIGINT;
            }
        }
        return funName;

    }

    public static String getNumExtractFuntion(Object value) {
        String funName = XbbConstant.JSON_EXTRACT_DOUBLE;
        if (value instanceof Integer) {
            funName = XbbConstant.JSON_EXTRACT_BIGINT;
        } /*else if (value instanceof String) {
                funName = XbbConstant.JSON_EXTRACT_STRING;
            }*/
        return funName;
    }

    /**
     * @param col
     * @return java.lang.String
     * @throws
     * @Description 生成argMax拼接串【由于特殊的去重方式，update字段需要特殊处理,as 后原字段重命名】
     * @Date 9:28 2022/1/13
     * @Param
     **/

    public static String generatargMax(String col) {
        if (!col.equals(XbbConstant.UPDATE_TIME)) {
            return "argMax(" + col + ",update_time) as " + col;
        } else {
            return "argMax(" + col + ",update_time) as t" + col;
        }
    }

    public static boolean getIsMaxPermission(BaseDTO baseDTO) {
        if (baseDTO != null) {
            UserVO loginUser = baseDTO.getLoginUser();
            if (loginUser != null) {
                return loginUser.isMaxDataPermission(true);
            }
        }
        return false;
    }

    /**
     * @return java.lang.String
     * @author gzt
     * @Description 添加团队名称Map缓存
     * @Date 14:57 2022/2/17
     **/

    public static String getTeamNameByBusinessType(Integer businessType) {
        String teamName = teamUserHashMap.get(businessType);
        if (StringUtils.isEmpty(teamName) && !Objects.isNull(businessType)) {
            teamName = XbbTableRefEnum.getTeamNameByParent(businessType);
            teamUserHashMap.putIfAbsent(businessType, teamName);
        }
        return teamName;
    }


    /**
     * @return java.lang.String
     * @author gzt
     * @Description updatetime字段 as 需要特殊处理
     * @Date 9:30 2022/1/17
     **/

    public static String renameUpdateTime(String col) {
        if (Objects.equals(XbbConstant.UPDATE_TIME, col)) {
            //数据集先不加t
            col = MessageFormat.format("t{0}", col);
        }
        return col;
    }

    /**
     * @param colWithPre
     * @return java.lang.String
     * @throws
     * @Description 由于特殊的去重方式，update字段需要特殊处理,as 后原字段重命名
     * @Date 9:28 2022/1/13
     **/
    protected String renameUpdateTimeWithPre(String colWithPre) {
        if (StringUtils.isNotEmpty(colWithPre) && colWithPre.contains(XbbConstant.UPDATE_TIME)) {
            colWithPre = colWithPre.replaceAll(XbbConstant.UPDATE_TIME, "t" + XbbConstant.UPDATE_TIME);
        }
        return colWithPre;
    }


    /**
     * @param conditionJson
     * @return boolean
     * @throws
     * @author gzt
     * @Description 是否公海, 参数conditionJson
     * @Date 8:54 2022/1/17
     * @update 统一移动到ChartUtil中，便于维护
     **/

    public static boolean isPublicFlag(Object conditionJson) {
        if (conditionJson != null) {
            if (conditionJson instanceof JSONObject) {
                if (getPublicFlag((JSONObject) conditionJson)) {
                    return true;
                }
            } else {
                JSONArray jsonArray = (JSONArray) conditionJson;
                for (Object o : jsonArray) {
                    if (getPublicFlag((JSONObject) o)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * @param o
     * @return boolean
     * @throws
     * @author gzt
     * @Description 是否公海, 参数JSONObject
     * @Date 8:56 2022/1/17
     * @update 统一移动到ChartUtil中，便于维护
     **/

    private static boolean getPublicFlag(JSONObject o) {
        JSONObject fJson = o;
        if (fJson != null) {
            Object saasAttr = fJson.get("saasAttr");
            if (Objects.equals(XbbConstant.IS_PUBLIC,saasAttr)) {
                ConditionsEntityExt condition = JSONObject.parseObject(fJson.toJSONString(), ConditionsEntityExt.class);
                List<Object> value = condition.getValue();
                if (CollectionHelper.isNotEmptyList(value)) {
                    if (Objects.equals(BasicConstant.ONE, value.get(0))) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * @author  gzt
     * @Description AS 字段转换
     * @Date 10:52 2022/9/16
     * @param asField
     * @return java.lang.String
     * @throws
     **/


    public static String getConvertAttr(String asField,Integer fieldType) {
        if (Objects.equals(FieldTypeEnum.OWNERID.getType(),fieldType)){
            asField = XbbConstant.MY_TEAM_MAIN + asField.split(XbbConstant.SEPARATOR)[1];

        }
        if (Objects.equals(FieldTypeEnum.COUSERID.getType(),fieldType)){
            asField = XbbConstant.MY_TEAM + asField.split(XbbConstant.SEPARATOR)[1];
        }
        return asField;
    }

    /**
     * 文本加引号
     *
     * @param fieldType
     * @param value
     * @return java.lang.Object
     * @author xinpeng.jiang
     * @date 2021/11/30 17:28
     * @version 1.0
     */
    public static Object handleText(Integer fieldType, Object value) {
        if (FieldTypeEnum.isTextType(fieldType)) {
            value = "'" + value + "'";
        }
        return value;
    }

    public static int getTeamIdx(String attr, int teamIdx) {
        if (StringUtils.isNotEmpty(attr) && attr.contains(XbbConstant.SEPARATOR)) {
            String teamIndex = attr.split(XbbConstant.SEPARATOR)[1];
            if (StringUtil.isDigital(teamIndex)) {
                teamIdx = Integer.parseInt(teamIndex);
            }
        }
        return teamIdx;
    }
}
